# 使用pygame绘制中国象棋棋盘和棋子并集成云库API
import pygame
import sys
import os
import requests
import json

# 完全移除tkinter导入，避免在macOS上出错
# import tkinter as tk
# from tkinter import messagebox


class ChineseChessRenderer:
    def _get_font(self, size):
        """获取可用的中文字体 - 简化并确保可靠性"""
        # 用于测试的棋子字符
        test_chars = "车车马炮"

        # 直接尝试最常用的系统字体文件
        # 首先尝试直接指定系统上最可能存在的中文字体文件路径

        # 硬编码的字体文件路径 - 增加找到有效字体的可能性
        hardcoded_font_paths = []

        # 添加Windows常见路径
        hardcoded_font_paths.extend(
            [
                "C:\\Windows\\Fonts\\simhei.ttf",
                "C:\\Windows\\Fonts\\msyh.ttc",
                "C:\\Windows\\Fonts\\simsun.ttc",
            ]
        )

        # 添加macOS常见路径
        hardcoded_font_paths.extend(
            [
                "/System/Library/Fonts/PingFang.ttc",
                "/Library/Fonts/SimHei.ttf",
                "/Library/Fonts/STHeiti Medium.ttc",
            ]
        )

        # 添加Linux常见路径
        hardcoded_font_paths.extend(
            [
                "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
                "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
            ]
        )

        # 首先尝试直接加载字体文件 - 这是最可靠的方法
        for font_path in hardcoded_font_paths:
            try:
                if os.path.exists(font_path):
                    font = pygame.font.Font(font_path, size)
                    # 测试字体是否能正确渲染中文字符
                    test_surf = font.render(test_chars, True, (0, 0, 0))
                    if test_surf.get_width() > 30:  # 确保至少渲染了一些内容
                        return font
            except Exception:
                continue

        # 其次尝试系统字体名称 - 使用最通用的字体名
        common_fonts = [
            ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "STHeiti"],  # 黑体系列
            ["Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC"],  # 无衬线字体
            ["SimSun", "STSong", "AR PL UMing CN"],  # 宋体系列
        ]

        # 对每组字体分别尝试
        for font_group in common_fonts:
            for font_name in font_group:
                try:
                    # 尝试加载字体，设置bold=False以提高兼容性
                    font = pygame.font.SysFont(font_name, size, bold=False)
                    test_surf = font.render(test_chars, True, (0, 0, 0))
                    if test_surf.get_width() > 30:
                        return font
                except Exception:
                    continue

        # 最后尝试pygame默认字体 - 这是最后的选择
        try:
            # 使用pygame默认字体，不指定名称
            default_font = pygame.font.Font(None, size)
            test_surf = default_font.render(test_chars, True, (0, 0, 0))
            # 即使默认字体可能无法正确显示中文，我们也返回它以避免崩溃
            return default_font
        except Exception:
            # 如果所有方法都失败，尝试最简单的字体创建方式
            return pygame.font.SysFont(None, size)

    def __init__(self, width=1600, height=900):
        # 初始化pygame
        pygame.init()
        # 设置中文字体支持
        pygame.font.init()
        self.width = width
        self.height = height
        self.screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("中国象棋智能棋盘")
        
        # 初始化棋子图片相关属性
        self.current_piece_style = 'DELICATE'  # 默认棋子风格，使用更有可能成功加载的风格
        self.piece_images = {}  # 存储不同风格的棋子图片
        
        # 初始化棋盘图片相关属性
        self.current_board_style = 'WOOD'  # 默认棋盘风格
        self.board_image = None  # 当前使用的棋盘背景图片
        self.board_images = {}  # 存储所有棋盘背景图片
        
        # 加载棋子图片
        self.load_piece_images()
        
        # 验证当前风格是否成功加载
        if not self.piece_images.get(self.current_piece_style):
            # 如果当前风格加载失败，尝试其他风格
            print(f"默认风格{self.current_piece_style}加载失败，尝试其他风格...")
            for style in ['DELICATE', 'POLISH', 'WOOD']:
                if style != self.current_piece_style and self.piece_images.get(style):
                    self.current_piece_style = style
                    print(f"切换到备用风格: {self.current_piece_style}")
                    break

        # 设置颜色
        self.BOARD_COLOR = (227, 193, 111)
        self.BORDER_COLOR = (139, 69, 19)  # 深棕色边框，更像实木
        self.LINE_COLOR = (0, 0, 0)
        self.TEXT_COLOR = (0, 0, 0)
        self.RED_COLOR = (205, 92, 92)
        self.BLACK_COLOR = (0, 0, 0)
        self.ARROW_COLOR = (255, 0, 0)  # 走法箭头颜色

        # 设置字体 - 改进字体选择，增加备选字体
        self.font = self._get_font(30)
        self.small_font = self._get_font(16)

        # 字体切换相关变量
        self.available_fonts = [
            "PingFang SC",
            "Heiti TC",
            "STHeiti",
            "STKaiti",
            "SimHei",
            "Microsoft YaHei",
            "WenQuanYi Micro Hei",
            "Arial Unicode MS",
            "Noto Sans CJK SC",
        ]
        self.current_font_index = 0
        self.current_font_name = self.available_fonts[self.current_font_index]

        # 修改棋盘布局参数，将棋盘移到左侧
        self.board_margin = 40  # 减小左侧边距
        # 中国象棋棋盘是9x10的交叉点
        # 为右侧预留600像素，因为之前要求增加50%
        self.cell_size = min(
            (width - self.board_margin - 800) // 8,  # 480像素用于右侧面板
            (height - 2 * self.board_margin) // 9,
        )
        self.board_width = 8 * self.cell_size
        self.board_height = 9 * self.cell_size
        self.board_x = self.board_margin  # 棋盘靠左
        self.board_y = (height - self.board_height) // 2  # 上下居中

        # 边框参数 - 保持足够大的边距确保能完整包含所有棋子
        self.border_margin = 35  # 足够大的边距确保包含所有棋子
        self.border_width = self.board_width + 2 * self.border_margin
        self.border_height = self.board_height + 2 * self.border_margin
        self.border_x = self.board_x - self.border_margin
        self.border_y = self.board_y - self.border_margin

        # 棋子映射字典
        self.piece_symbols = {
            "r": ("车", self.BLACK_COLOR),
            "R": ("車", self.RED_COLOR),
            "n": ("马", self.BLACK_COLOR),
            "N": ("馬", self.RED_COLOR),
            "b": ("象", self.BLACK_COLOR),
            "B": ("相", self.RED_COLOR),
            "a": ("士", self.BLACK_COLOR),
            "A": ("仕", self.RED_COLOR),
            "k": ("将", self.BLACK_COLOR),
            "K": ("帥", self.RED_COLOR),
            "c": ("砲", self.BLACK_COLOR),
            "C": ("炮", self.RED_COLOR),
            "p": ("卒", self.BLACK_COLOR),
            "P": ("兵", self.RED_COLOR),
        }

        # 反向映射，用于从中文符号获取FEN字符 - 修正黑棋变红的问题
        # 创建两个映射表，一个用于黑棋，一个用于红棋
        self.symbol_to_fen_black = {
            v[0]: k for k, v in self.piece_symbols.items() if v[1] == self.BLACK_COLOR
        }
        self.symbol_to_fen_red = {
            v[0]: k for k, v in self.piece_symbols.items() if v[1] == self.RED_COLOR
        }
        # 保留原来的映射，但优先使用新的颜色特定映射
        self.symbol_to_fen = {v[0]: k for k, v in self.piece_symbols.items()}

        # 用于棋子拖拽
        self.dragging = False
        self.dragged_piece = None
        self.drag_pos = (0, 0)
        self.selected_pos = None
        # 添加移动标记属性的初始设置
        self.move_start_pos = None
        self.move_end_pos = None

        # 用于闪烁效果
        self.flash_position = None
        self.flash_timer = 0
        self.flash_count = 0

        # 文本输入框状态
        self.input_active = False
        self.input_text = ""
        self.input_box = pygame.Rect(20, height - 60, width - 40, 30)
        self.input_color = pygame.Color("lightskyblue3")
        self.active_color = pygame.Color("dodgerblue2")

        # 云库API设置
        self.chessdb_api_url = "http://www.chessdb.cn/chessdb.php"
        self.api_results = []
        self.show_api_results = False
        
        # LLM文字解说相关属性
        self.llm_commentary = ""
        self.llm_commentary_url = "https://www.chessdb.cn/llm.php"
        self.llm_commentary_loading = False
        
        # 推荐走法信息
        self.current_move = None
        self.current_move_text = ""
        self.current_move_score = None
        self.current_move_winrate = None

        # 添加红方和黑方最优走法属性
        self.red_best_move = None
        self.red_best_move_text = ""
        self.red_best_move_score = None
        self.red_best_move_winrate = None
        self.red_best_move_chinese = ""
        
        self.black_best_move = None
        self.black_best_move_text = ""
        self.black_best_move_score = None
        self.black_best_move_winrate = None
        self.black_best_move_chinese = ""

        # 添加存储第二步最优走法的属性
        self.red_second_move = None
        self.red_second_move_text = ""
        self.red_second_move_score = None
        self.red_second_move_winrate = None

        self.black_second_move = None
        self.black_second_move_text = ""
        self.black_second_move_score = None
        self.black_second_move_winrate = None

        # 保存最后一步的中文棋步
        self.last_chinese_move = ""

        # 添加显示箭头的控制属性
        self.show_move_arrow = True  # 默认显示走法箭头

        # 用于存储历史分数点，以便绘制曲线
        self.history_red_scores = []
        self.history_black_scores = []
        self.max_history_points = 10  # 最多保存10个历史点
        
        # 图片相关属性
        # 注意：current_piece_style和piece_images已在__init__方法中初始化
        # self.current_piece_style = "WOOD"  # 移除重复设置，避免覆盖__init__中的设置
        self.board_image = None

        # 按钮相关属性 - 调整按钮位置到右侧面板
        # 右侧面板宽度统一为480像素
        right_panel_width = 560  # 面板实际宽度
        right_panel_x = self.width + 10 - right_panel_width

        self.reset_button = pygame.Rect(
            right_panel_x, self.height - 190, right_panel_width - 10, 40
        )
        self.flip_button = pygame.Rect(
            right_panel_x, self.height - 140, right_panel_width - 10, 40
        )
        # 添加悔棋按钮
        self.undo_button = pygame.Rect(
            right_panel_x, self.height - 240, right_panel_width - 10, 40
        )
        self.font_button = pygame.Rect(
            right_panel_x, self.height - 90, right_panel_width - 10, 40
        )
        self.button_color = (70, 130, 180)  # 按钮默认颜色
        self.button_hover_color = (100, 150, 200)  # 按钮悬停颜色
        self.button_text_color = (255, 255, 255)  # 按钮文本颜色
        self.button_border_radius = 5  # 按钮圆角半径

        # 棋盘翻转状态
        self.board_flipped = False
        
        # 添加FEN历史记录属性，用于悔棋功能
        self.fen_history = []
        
        # 添加点击走子相关属性
        self.move_start_pos = None  # 存储走子起点位置
        self.move_end_pos = None    # 存储走子终点位置

    def _parse_move(self, move_text):
        """解析走法字符串，如'b0a2'，返回棋盘坐标"""
        if len(move_text) != 4:
            return None

        try:
            # 云库走法格式: 列+行+目标列+目标行
            # 例如: b0a2 表示从第2列第0行移动到第1列第2行
            from_col_char, from_row_char, to_col_char, to_row_char = move_text

            # 转换列字符到索引 (a=0, b=1, ..., i=8)
            from_col = ord(from_col_char.lower()) - ord("a")
            to_col = ord(to_col_char.lower()) - ord("a")

            # 转换行字符到索引
            from_row = int(from_row_char)
            to_row = int(to_row_char)

            # 验证坐标是否有效
            if (
                0 <= from_col < 9
                and 0 <= from_row < 10
                and 0 <= to_col < 9
                and 0 <= to_row < 10
            ):
                return (from_col, from_row, to_col, to_row)
            return None
        except:
            return None

    def _coord_to_chinese_move(self, fen, from_col, from_row, to_col, to_row):
        """将坐标转换为中文棋步描述，如'马二进三'、'炮八平五'，严格按照中国象棋规则"""
        # 获取棋盘状态
        board = self.fen_to_board(fen)
        
        # 添加调试信息
        print(f"调试 - FEN: {fen}")
        print(f"调试 - 坐标: ({from_row},{from_col}) -> ({to_row},{to_col})")
        print(f"调试 - 棋盘是否翻转: {self.board_flipped}")
        
        # 如果棋盘翻转，调整坐标
        if self.board_flipped:
            # 翻转列坐标 (0<->8, 1<->7, ..., 4<->4)
            from_col = 8 - from_col
            to_col = 8 - to_col
            # 翻转行坐标 (0<->9, 1<->8, ..., 4<->5)
            from_row = 9 - from_row
            to_row = 9 - to_row
            print(f"调试 - 翻转后坐标: ({from_row},{from_col}) -> ({to_row},{to_col})")
        
        # 检查坐标是否有效
        if not (
            0 <= from_col < 9
            and 0 <= from_row < 10
            and 0 <= to_col < 9
            and 0 <= to_row < 10
        ):
            return "无效移动：坐标超出棋盘范围"
        
        # 修复：确保索引不越界
        if from_row >= len(board) or from_col >= len(board[from_row]):
            return f"无效移动：坐标 ({from_row},{from_col}) 超出棋盘实际范围"
        
        piece_char = board[from_row][from_col]

        # 检查是否有棋子
        if piece_char == "." or piece_char not in self.piece_symbols:
            return f"无效移动：该位置没有棋子或棋子字符无效 ({piece_char})"

        # 确定棋子颜色和类型
        piece_info = self.piece_symbols[piece_char]
        piece_name = piece_info[0]
        is_red_piece = piece_info[1] == self.RED_COLOR

        # 中国象棋的数字表示 (1-9)
        chinese_nums = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"]

        # 从棋盘坐标转换为中国象棋记谱坐标
        # 注意：红方和黑方的视角不同，列的编号方式相反
        if is_red_piece:
            # 红方视角：列从右到左为1-9
            from_col_num = 9 - from_col
            to_col_num = 9 - to_col
        else:
            # 黑方视角：列从左到右为1-9
            from_col_num = from_col + 1
            to_col_num = to_col + 1

        # 行坐标：红方和黑方都是从己方底线开始数1-10
        if is_red_piece:
            # 红方：从下往上数（0行是黑方底线，9行是红方底线）
            from_row_num = 10 - from_row
            to_row_num = 10 - to_row
        else:
            # 黑方：从上往下数
            from_row_num = from_row + 1
            to_row_num = to_row + 1

        # 确定移动类型：进、退、平
        move_type = ""

        # 特殊处理马、象、士的移动方向判断
        if piece_name in ["马", "象", "士"]:
            # 对于马、象、士："进"是指向对方底线方向移动，"退"是指向己方底线方向移动
            # 确定移动方向是否朝向对方底线
            if is_red_piece:
                # 红方：to_row < from_row 是向对方底线方向移动
                if to_row < from_row:
                    move_type = "进"
                else:
                    move_type = "退"
            else:
                # 黑方：to_row > from_row 是向对方底线方向移动
                if to_row > from_row:
                    move_type = "进"
                else:
                    move_type = "退"
        elif from_col == to_col:
            # 车、炮、兵：同一列，进或退
            if is_red_piece:
                # 红方：向前（向黑方）移动为进（行号减小），向后（向己方）移动为退（行号增大）
                if to_row < from_row:  # 红方棋子向上移动（向黑方方向）
                    move_type = "进"
                else:  # 红方棋子向下移动（向己方方向）
                    move_type = "退"
            else:
                # 黑方：向前（向红方）移动为进（行号增大），向后（向己方）移动为退（行号减小）
                if to_row > from_row:  # 黑方棋子向下移动（向红方方向）
                    move_type = "进"
                else:  # 黑方棋子向上移动（向己方方向）
                    move_type = "退"
        else:
            # 不同列，平
            move_type = "平"

        # 构建中文棋步
        # 对于同一列移动（进/退），使用目标行号
        # 对于不同列移动（平），使用目标列号
        target_num = to_row_num if move_type in ["进", "退"] else to_col_num

        # 更严格的边界检查，确保所有用于索引的数字都在有效范围内
        if not (1 <= from_col_num <= 9):
            return f"无效移动：起始列超出有效范围({from_col_num})"
        if not (1 <= target_num <= 9):
            return f"无效移动：目标位置超出有效范围({target_num})"

        # 根据用户要求的格式调整：
        # 1. 红方在前加"红 "
        # 2. 黑方在前加"黑"
        # 3. 红方使用中文数字，黑方使用阿拉伯数字
        color_prefix = "红 " if is_red_piece else "黑"

        try:
            if is_red_piece:
                # 红方使用中文数字
                from_num_str = chinese_nums[from_col_num]
                target_num_str = chinese_nums[target_num]
            else:
                # 黑方使用阿拉伯数字
                from_num_str = str(from_col_num)
                target_num_str = str(target_num)
        except IndexError as e:
            # 最后的安全网，捕获任何索引错误
            return f"棋步转换错误：索引超出范围 - {str(e)}"

        # 构建完整的棋步描述
        chinese_move = (
            f"{color_prefix}{piece_name}{from_num_str}{move_type}{target_num_str}"
        )

        return chinese_move

    def draw_board(self):
        """绘制棋盘，支持翻转，优先使用图片"""
        # 绘制背景
        self.screen.fill((240, 240, 240))
        
        # 优先使用加载的棋盘图片
        if self.board_image:
            # 计算边框区域的尺寸和位置
            border_width = self.border_width
            border_height = self.border_height
            border_x = self.border_x
            border_y = self.border_y
            
            # 调整图片大小以适应边框区域
            scaled_board = pygame.transform.scale(self.board_image, (border_width, border_height))
            # 绘制棋盘图片
            self.screen.blit(scaled_board, (border_x, border_y))
        else:
            # 如果没有加载到棋盘图片，使用原来的绘制代码作为后备
            # 绘制外层边框 - 深色实木边框效果
            pygame.draw.rect(
                self.screen,
                self.BORDER_COLOR,
                (self.border_x, self.border_y, self.border_width, self.border_height),
                0,
            )  # 填充边框

            # 添加边框高光效果，创建立体感
            pygame.draw.rect(
                self.screen,
                (180, 130, 70),
                (self.border_x, self.border_y, self.border_width, self.border_height),
                3,
            )  # 边框外轮廓线

            # 添加内边框线条，增强层次感
            pygame.draw.rect(
                self.screen,
                (101, 67, 33),
                (
                    self.border_x + 5,
                    self.border_y + 5,
                    self.border_width - 10,
                    self.border_height - 10,
                ),
                2,
            )  # 内边框线

            # 绘制棋盘底色 - 在边框内部
            pygame.draw.rect(
                self.screen,
                self.BOARD_COLOR,
                (self.board_x, self.board_y, self.board_width, self.board_height),
            )

            # 绘制横线 - 修复楚河汉界行没有横线的问题
            for i in range(10):
                # 处理行的翻转
                row_idx = i if not self.board_flipped else 9 - i
                y = self.board_y + row_idx * self.cell_size
                # 所有行都绘制完整的横线
                pygame.draw.line(
                    self.screen,
                    self.LINE_COLOR,
                    (self.board_x, y),
                    (self.board_x + self.board_width, y),
                    2,
                )

            # 绘制竖线
            # 楚河汉界位置：第4行和第5行之间
            river_y1 = self.board_y + 4 * self.cell_size  # 第4行线
            river_y2 = self.board_y + 5 * self.cell_size  # 第5行线

            for i in range(9):
                # 处理列的翻转
                col_idx = i if not self.board_flipped else 8 - i
                x = self.board_x + col_idx * self.cell_size

                if i == 0 or i == 8:  # 棋盘两侧的竖线（列0和列8）保持完整
                    pygame.draw.line(
                        self.screen,
                        self.LINE_COLOR,
                        (x, self.board_y),
                        (x, self.board_y + self.board_height),
                        3,
                    )  # 加粗显示
                else:  # 中间的竖线在楚河汉界处断开
                    # 上半部分竖线
                    pygame.draw.line(
                        self.screen, self.LINE_COLOR, (x, self.board_y), (x, river_y1), 2
                    )
                    # 下半部分竖线
                    pygame.draw.line(
                        self.screen,
                        self.LINE_COLOR,
                        (x, river_y2),
                        (x, self.board_y + self.board_height),
                        2,
                    )

            # 绘制九宫格斜线 - 修正斜线位置和长度
            # 黑方九宫
            pygame.draw.line(
                self.screen,
                self.LINE_COLOR,
                (self.board_x + 3 * self.cell_size, self.board_y),
                (self.board_x + 5 * self.cell_size, self.board_y + 2 * self.cell_size),
                2,
            )
            pygame.draw.line(
                self.screen,
                self.LINE_COLOR,
                (self.board_x + 5 * self.cell_size, self.board_y),
                (self.board_x + 3 * self.cell_size, self.board_y + 2 * self.cell_size),
                2,
            )
            # 红方九宫
            pygame.draw.line(
                self.screen,
                self.LINE_COLOR,
                (self.board_x + 3 * self.cell_size, self.board_y + 7 * self.cell_size),
                (self.board_x + 5 * self.cell_size, self.board_y + 9 * self.cell_size),
                2,
            )
            pygame.draw.line(
                self.screen,
                self.LINE_COLOR,
                (self.board_x + 5 * self.cell_size, self.board_y + 7 * self.cell_size),
                (self.board_x + 3 * self.cell_size, self.board_y + 9 * self.cell_size),
                2,
            )

            # 绘制兵和炮的初始位置标记 - 已修正位置
            # 炮的位置：红方在第1行(索引0)，列1和7；黑方在第8行(索引7)，列1和7
            for i in [1, 7]:  # 列1和列7
                col_idx = i if not self.board_flipped else 8 - i
                # 红方炮（上方）
                x1 = self.board_x + col_idx * self.cell_size
                y1 = self.board_y + 0 * self.cell_size
                pygame.draw.circle(self.screen, (255, 0, 0), (x1, y1), 6, 2)  # 红色实线圆圈

                # 黑方炮（下方） - 修正为正确行索引
                x2 = self.board_x + col_idx * self.cell_size
                y2 = self.board_y + 7 * self.cell_size
                pygame.draw.circle(self.screen, (255, 0, 0), (x2, y2), 6, 2)  # 红色实线圆圈

            # 兵的位置：红方在第3行(索引2)，列0,2,4,6,8；黑方在第6行(索引5)，列0,2,4,6,8
            # 修正：根据中国象棋标准布局，兵的位置需要调整
            # 红方兵（上方） - 修正为第3行
            for i in [0, 2, 4, 6, 8]:  # 列0,2,4,6,8
                col_idx = i if not self.board_flipped else 8 - i
                x1 = self.board_x + col_idx * self.cell_size
                y1 = self.board_y + 2 * self.cell_size
                pygame.draw.circle(self.screen, (0, 0, 0), (x1, y1), 6, 2)  # 黑色实线圆圈

            # 黑方卒（下方） - 修正为第6行
            for i in [0, 2, 4, 6, 8]:  # 列0,2,4,6,8
                col_idx = i if not self.board_flipped else 8 - i
                x2 = self.board_x + col_idx * self.cell_size
                y2 = self.board_y + 5 * self.cell_size
                pygame.draw.circle(self.screen, (0, 0, 0), (x2, y2), 6, 2)  # 黑色实线圆圈

            # 绘制河界文字 - 改进文字位置和显示效果
            river_font = self._get_font(int(self.cell_size * 0.6))  # 动态调整字体大小

            # 计算文本位置使其居中，根据翻转状态调整
            if not self.board_flipped:
                river_text1 = river_font.render("楚河", True, self.TEXT_COLOR)
                text1_rect = river_text1.get_rect(
                    center=(
                        self.board_x + 2 * self.cell_size,
                        self.board_y + 4.5 * self.cell_size,
                    )
                )
                self.screen.blit(river_text1, text1_rect)

                river_text2 = river_font.render("汉界", True, self.TEXT_COLOR)
                text2_rect = river_text2.get_rect(
                    center=(
                        self.board_x + 6 * self.cell_size,
                        self.board_y + 4.5 * self.cell_size,
                    )
                )
                self.screen.blit(river_text2, text2_rect)
            else:
                # 翻转时交换楚河汉界的位置
                river_text1 = river_font.render("汉界", True, self.TEXT_COLOR)
                text1_rect = river_text1.get_rect(
                    center=(
                        self.board_x + 2 * self.cell_size,
                        self.board_y + 4.5 * self.cell_size,
                    )
                )
                self.screen.blit(river_text1, text1_rect)

                river_text2 = river_font.render("楚河", True, self.TEXT_COLOR)
                text2_rect = river_text2.get_rect(
                    center=(
                        self.board_x + 6 * self.cell_size,
                        self.board_y + 4.5 * self.cell_size,
                    )
                )
                self.screen.blit(river_text2, text2_rect)

        # 绘制坐标标记 - 修正坐标显示
        for i in range(9):
            # 上方坐标
            text = self.small_font.render(str(9 - i), True, self.TEXT_COLOR)
            self.screen.blit(
                text,
                (
                    self.board_x + i * self.cell_size - text.get_width() // 2,
                    self.board_y - 25,
                ),
            )
            # 下方坐标
            self.screen.blit(
                text,
                (
                    self.board_x + i * self.cell_size - text.get_width() // 2,
                    self.board_y + self.board_height + 5,
                ),
            )

            # 左侧坐标
            text = self.small_font.render(chr(ord("9") - i), True, self.TEXT_COLOR)
            self.screen.blit(
                text,
                (
                    self.board_x - 25,
                    self.board_y + i * self.cell_size - text.get_height() // 2,
                ),
            )
            # 右侧坐标
            self.screen.blit(
                text,
                (
                    self.board_x + self.board_width + 5,
                    self.board_y + i * self.cell_size - text.get_height() // 2,
                ),
            )

        # 绘制闪烁效果
        if self.flash_position and self.flash_count < 5:
            current_time = pygame.time.get_ticks()
            # 每100毫秒闪烁一次
            if current_time - self.flash_timer > 100:
                self.flash_timer = current_time
                self.flash_count += 1

            # 奇数次数显示闪烁
            if self.flash_count % 2 == 1:
                row, col = self.flash_position
                x = self.board_x + col * self.cell_size
                y = self.board_y + row * self.cell_size
                # 绘制一个较大的、半透明的圆圈作为闪烁提示
                pygame.draw.circle(
                    self.screen, (255, 255, 0), (x, y), self.cell_size // 3, 2
                )

        # 绘制推荐走法箭头
        self.draw_move_arrow()

    def draw_move_arrow(self):
        """绘制推荐走法的箭头"""
        if not self.show_move_arrow:
            return

        # 定义不同颜色
        RED_ARROW_COLOR = (255, 0, 0)  # 红先箭头颜色（第一步）
        RED_ARROW_COLOR_2 = (255, 100, 100)  # 红先箭头颜色（第二步）
        BLACK_ARROW_COLOR = (0, 0, 255)  # 黑先箭头颜色（第一步）
        BLACK_ARROW_COLOR_2 = (100, 100, 255)  # 黑先箭头颜色（第二步）

        # 绘制当前推荐走法（使用原有颜色）
        if self.current_move:
            self._draw_single_arrow(
                self.current_move,
                self.ARROW_COLOR,
                self.current_move_score,
                self.current_move_winrate,
            )

        # 绘制红先最优走法（两步）
        if self.red_best_move:
            self._draw_single_arrow(
                self.red_best_move,
                RED_ARROW_COLOR,
                self.red_best_move_score,
                self.red_best_move_winrate,
            )
        if self.red_second_move:
            self._draw_single_arrow(
                self.red_second_move,
                RED_ARROW_COLOR_2,
                self.red_second_move_score,
                self.red_second_move_winrate,
            )

        # 绘制黑先最优走法（两步）
        if self.black_best_move:
            self._draw_single_arrow(
                self.black_best_move,
                BLACK_ARROW_COLOR,
                self.black_best_move_score,
                self.black_best_move_winrate,
            )
        if self.black_second_move:
            self._draw_single_arrow(
                self.black_second_move,
                BLACK_ARROW_COLOR_2,
                self.black_second_move_score,
                self.black_second_move_winrate,
            )

    def draw_move_markers(self):
        """绘制走子标记（起点和终点的同心圆）"""
        # 绘制起点标记（蓝色同心圆）
        if self.move_start_pos:
            row, col = self.move_start_pos
            # 根据翻转状态计算显示位置
            if self.board_flipped:
                display_col = 8 - col
                display_row = 9 - row
            else:
                display_col = col
                display_row = row
            
            center_x = self.board_x + display_col * self.cell_size
            center_y = self.board_y + display_row * self.cell_size
            radius = self.cell_size * 0.4
            
            # 绘制蓝色外圈
            pygame.draw.circle(self.screen, (0, 0, 255), (center_x, center_y), radius + 5, 3)
            # 绘制浅蓝色中圈
            pygame.draw.circle(self.screen, (100, 100, 255), (center_x, center_y), radius + 2, 2)
        
        # 绘制终点标记（绿色同心圆）
        if self.move_end_pos:
            row, col = self.move_end_pos
            # 根据翻转状态计算显示位置
            if self.board_flipped:
                display_col = 8 - col
                display_row = 9 - row
            else:
                display_col = col
                display_row = row
            
            center_x = self.board_x + display_col * self.cell_size
            center_y = self.board_y + display_row * self.cell_size
            radius = self.cell_size * 0.4
            
            # 绘制绿色外圈
            pygame.draw.circle(self.screen, (0, 255, 0), (center_x, center_y), radius + 5, 3)
            # 绘制浅绿色中圈
            pygame.draw.circle(self.screen, (100, 255, 100), (center_x, center_y), radius + 2, 2)

    def convert_single_move_to_chinese(self, move):
        """将单个move坐标转换为中文棋步"""
        if not move or len(move) != 4:
            return "无效走法"

        # 解析坐标
        from_col, from_row, to_col, to_row = move

        # 构建当前棋盘的FEN（使用当前board_part和turn）
        # 注意：这里需要确保board_part和current_turn是可用的
        if hasattr(self, "board_part") and hasattr(self, "current_turn"):
            full_fen = f"{self.board_part} {self.current_turn} - - 0 1"
            try:
                return self._coord_to_chinese_move(
                    full_fen, from_col, from_row, to_col, to_row
                )
            except Exception as e:
                return f"转换失败: {str(e)}"

        # 如果没有完整棋盘信息，返回基本描述
        return f"从({from_col},{from_row})到({to_col},{to_row})"

    def _draw_single_arrow(self, move, color, score=None, winrate=None):
        """绘制单个箭头并显示相关信息"""
        from_col, from_row, to_col, to_row = move

        # 计算起点和终点的屏幕坐标
        # 修复箭头方向问题：棋盘坐标系和屏幕坐标系的y轴方向相反
        start_x = self.board_x + from_col * self.cell_size
        start_y = self.board_y + (9 - from_row) * self.cell_size  # 翻转y轴方向
        end_x = self.board_x + to_col * self.cell_size
        end_y = self.board_y + (9 - to_row) * self.cell_size  # 翻转y轴方向

        # 计算箭头方向
        dx = end_x - start_x
        dy = end_y - start_y
        # 计算箭头长度
        length = (dx**2 + dy**2) ** 0.5
        if length > 0:
            # 归一化方向向量
            dx /= length
            dy /= length

            # 绘制梯形而不是直线，起点宽一些，终点窄一些
            # 计算垂直于箭头方向的法向量
            perp_dx = -dy
            perp_dy = dx

            # 设置起点和终点的宽度
            start_width = 8  # 起点宽度
            end_width = 4  # 终点宽度

            # 计算梯形的终点位置，不要到达实际的移动终点，留出空间给箭头三角形
            # 根据箭头大小调整梯形终点位置
            arrow_size = 25  # 箭头大小
            # 梯形终点距离实际终点的距离（大约是箭头大小的0.6倍）
            distance_from_end = arrow_size * 0.6
            # 计算梯形的终点坐标
            trapezoid_end_x = end_x - dx * distance_from_end
            trapezoid_end_y = end_y - dy * distance_from_end

            # 计算梯形的四个顶点
            p1_x = start_x + perp_dx * start_width
            p1_y = start_y + perp_dy * start_width
            p2_x = start_x - perp_dx * start_width
            p2_y = start_y - perp_dy * start_width
            p3_x = trapezoid_end_x - perp_dx * end_width
            p3_y = trapezoid_end_y - perp_dy * end_width
            p4_x = trapezoid_end_x + perp_dx * end_width
            p4_y = trapezoid_end_y + perp_dy * end_width

            # 创建一个半透明的颜色用于填充梯形
            # 先将颜色转换为pygame.Color对象
            fill_color = pygame.Color(*color)
            # 创建一个新的surface用于绘制半透明梯形
            temp_surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
            # 绘制半透明梯形（alpha值设为80，范围0-255，值越低越透明）
            pygame.draw.polygon(
                temp_surface,
                (*color, 80),
                [(p1_x, p1_y), (p2_x, p2_y), (p3_x, p3_y), (p4_x, p4_y)],
            )
            # 将临时surface绘制到主屏幕上
            self.screen.blit(temp_surface, (0, 0))

            # 绘制箭头头部（简单的三角形）
            # 计算箭头头部的两个点
            arrow_size = 25  # 已调整为更大的箭头大小
            p_arrow1_x = end_x - arrow_size * (dx * 0.866 - dy * 0.5)
            p_arrow1_y = end_y - arrow_size * (dx * 0.5 + dy * 0.866)
            p_arrow2_x = end_x - arrow_size * (dx * 0.866 + dy * 0.5)
            p_arrow2_y = end_y - arrow_size * (-dx * 0.5 + dy * 0.866)

            # 绘制箭头三角形 - 使用半透明颜色，与梯形保持一致
            pygame.draw.polygon(
                temp_surface,
                (*color, 80),
                [(end_x, end_y), (p_arrow1_x, p_arrow1_y), (p_arrow2_x, p_arrow2_y)],
            )
            # 将箭头三角形绘制到主屏幕上
            self.screen.blit(temp_surface, (0, 0))

        # 在箭头旁边显示分数和胜率信息
        info_font = self._get_font(14)
        info_texts = []
        # 结合 fen和move 生成chinese_move
        chinese_move = self.convert_single_move_to_chinese(move)

        # 修复语法错误，正确设置默认值
        if not chinese_move:
            chinese_move = 'N/A'
        if score is None:
            score = 0
        if winrate is None:
            winrate = 0.0
            
        info_texts.append(f"Move: {chinese_move} Score: {score}|Winrate: {winrate:.2f}%")

        if info_texts:
            # 计算文本位置（箭头旁边）
            # 根据箭头方向确定文本应该显示的位置
            text_x = (
                (start_x + end_x) // 2 + 15
                if abs(dx) > abs(dy)
                else (start_x + end_x) // 2
            )
            text_y = (
                (start_y + end_y) // 2
                if abs(dx) > abs(dy)
                else (start_y + end_y) // 2 + 15
            )

            # 如果箭头向右或向下，文本应该放在右侧或下方
            if dx > 0 or dy > 0:
                text_x += 10
                text_y += 10
            else:
                text_x -= 100  # 为左对齐文本留出空间
                text_y -= 30

            # 绘制文本背景（半透明）以便于阅读
            max_width = 0
            for text in info_texts:
                text_width = info_font.size(text)[0]
                if text_width > max_width:
                    max_width = text_width

            # 绘制背景矩形
            bg_rect = pygame.Rect(
                text_x - 5, text_y - 5, max_width + 10, len(info_texts) * 20 + 5
            )
            pygame.draw.rect(
                self.screen, (255, 255, 255, 180), bg_rect, border_radius=3
            )
            pygame.draw.rect(self.screen, color, bg_rect, 1, border_radius=3)

            # 绘制文本
            for i, text in enumerate(info_texts):
                text_surface = info_font.render(text, True, color)
                self.screen.blit(text_surface, (text_x, text_y + i * 20))

    def draw_pieces(self, fen):
        """根据FEN字符串绘制棋子（使用图片），支持翻转"""
        # 解析FEN字符串，获取棋盘部分
        board_part = fen.split()[0]
        ranks = board_part.split("/")

        # 计算棋子大小
        piece_size = int(self.cell_size * 0.9)  # 棋子大小为格子的90%
        
        # 检查当前风格是否加载成功
        current_style_images = self.piece_images.get(self.current_piece_style, {})
        if not current_style_images:
            print(f"警告：未加载到{self.current_piece_style}风格的棋子图片")
            return
        
        # 先绘制所有非拖拽状态的棋子
        for rank_idx, rank in enumerate(ranks):
            file_idx = 0
            for char in rank:
                if char.isdigit():
                    # 数字表示空位置
                    file_idx += int(char)
                else:
                    # 检查是否为被拖拽的棋子
                    if not self.dragging or (rank_idx, file_idx) != self.selected_pos:
                        # 处理翻转
                        display_rank = (
                            rank_idx if not self.board_flipped else 9 - rank_idx
                        )
                        display_file = (
                            file_idx if not self.board_flipped else 8 - file_idx
                        )

                        # 计算棋子位置
                        x = self.board_x + display_file * self.cell_size
                        y = self.board_y + display_rank * self.cell_size

                        # 获取棋子图片
                        if char in current_style_images:
                            piece_img = current_style_images[char]
                            if piece_img:
                                # 调整图片大小
                                scaled_img = pygame.transform.scale(piece_img, (piece_size, piece_size))
                                # 计算图片位置使其居中
                                img_rect = scaled_img.get_rect(center=(x, y))
                                # 绘制棋子图片
                                self.screen.blit(scaled_img, img_rect)
                        else:
                            # 如果没有对应的图片，使用默认绘制方式作为后备
                            print(f"未找到棋子{char}的图片，使用默认绘制")
                            # 绘制棋子圆圈
                            radius = int(self.cell_size * 0.4)
                            pygame.draw.circle(
                                self.screen,
                                self.RED_COLOR if char.isupper() else self.BLACK_COLOR,
                                (x, y),
                                radius,
                                0,
                            )
                            # 绘制棋子边框
                            pygame.draw.circle(
                                self.screen, self.BORDER_COLOR, (x, y), radius, 2
                            )
                            # 绘制棋子文字
                            piece_text = self.font.render(self.piece_symbols[char][0], True, self.TEXT_COLOR)
                            text_rect = piece_text.get_rect(center=(x, y))
                            self.screen.blit(piece_text, text_rect)
                        
                        # 如果是选中位置，绘制选中状态
                        if self.selected_pos == (rank_idx, file_idx):
                            # 绘制选中效果的图片
                            if 'selected' in current_style_images:
                                selected_img = current_style_images['selected']
                                if selected_img:
                                    scaled_selected = pygame.transform.scale(selected_img, (piece_size, piece_size))
                                    selected_rect = scaled_selected.get_rect(center=(x, y))
                                    self.screen.blit(scaled_selected, selected_rect)
                            else:
                                # 后备方案：绘制选中圆圈
                                pygame.draw.circle(
                                    self.screen,
                                    (0, 0, 255),
                                    (x, y),
                                    radius + 5,
                                    3,
                                )

                    file_idx += 1

        # 绘制被拖拽的棋子
        if self.dragging and self.dragged_piece:
            symbol, color = self.dragged_piece
            
            # 获取对应棋子的FEN字符
            fen_char = None
            for key, (sym, col) in self.piece_symbols.items():
                if sym == symbol and col == color:
                    fen_char = key
                    break
            
            if fen_char and fen_char in current_style_images:
                # 获取拖拽棋子的图片
                dragged_img = current_style_images[fen_char]
                if dragged_img:
                    # 调整图片大小
                    scaled_dragged = pygame.transform.scale(dragged_img, (piece_size, piece_size))
                    # 获取鼠标位置并绘制棋子
                    mouse_pos = pygame.mouse.get_pos()
                    img_rect = scaled_dragged.get_rect(center=mouse_pos)
                    self.screen.blit(scaled_dragged, img_rect)
            else:
                # 后备方案：使用默认绘制方式
                mouse_pos = pygame.mouse.get_pos()
                radius = int(self.cell_size * 0.4)
                pygame.draw.circle(
                    self.screen,
                    self.RED_COLOR if color == 'red' else self.BLACK_COLOR,
                    mouse_pos,
                    radius,
                    0,
                )
                pygame.draw.circle(
                    self.screen, self.BORDER_COLOR, mouse_pos, radius, 2
                )
                piece_text = self.font.render(symbol, True, self.TEXT_COLOR)
                text_rect = piece_text.get_rect(center=mouse_pos)
                self.screen.blit(piece_text, text_rect)

    def draw_best_moves(self):
        """绘制红黑双方的最优招法"""
        # 直接调用已有的draw_move_arrow方法，它已经实现了绘制最优走法的功能
        self.draw_move_arrow()

    def draw_llm_commentary(self):
        """绘制LLM文字解说，位于趋势图上方"""
        # 右侧面板参数
        right_panel_x = self.width - 470
        right_panel_width = 460
        
        # 计算解说区域的位置，在趋势图上方
        curve_y = self.height - 400  # 从draw_score_curve方法中获取的曲线Y位置
        commentary_y = self.status_info_bottom_y + 20  # 在状态信息下方20像素
        commentary_height = curve_y - commentary_y - 10  # 到趋势图上方留10像素间距
        
        # 绘制背景框
        pygame.draw.rect(
            self.screen,
            (250, 250, 250),
            (right_panel_x, commentary_y, right_panel_width, commentary_height),
            border_radius=5,
        )
        pygame.draw.rect(
            self.screen,
            (0, 0, 0),
            (right_panel_x, commentary_y, right_panel_width, commentary_height),
            1,
            border_radius=5,
        )
        
        # 绘制标题
        font = self._get_font(16)
        title = font.render("局面解说", True, self.TEXT_COLOR)
        self.screen.blit(title, (right_panel_x + 10, commentary_y + 5))
        
        # 绘制分隔线
        pygame.draw.line(
            self.screen,
            (180, 180, 180),
            (right_panel_x, commentary_y + 25),
            (right_panel_x + right_panel_width, commentary_y + 25),
            1
        )
        
        # 绘制解说内容
        content_font = self._get_font(14)
        content_y = commentary_y + 30
        max_content_height = commentary_height - 35
        
        # 处理加载状态
        if self.llm_commentary_loading:
            loading_text = content_font.render("正在获取解说...", True, (128, 128, 128))
            self.screen.blit(loading_text, (right_panel_x + 15, content_y))
            return
        
        # 如果没有解说内容
        if not self.llm_commentary:
            no_content_text = content_font.render("暂无解说内容", True, (128, 128, 128))
            self.screen.blit(no_content_text, (right_panel_x + 15, content_y))
            return
        
        # 绘制多行解说内容，自动换行
        words = self.llm_commentary.split()
        current_line = ""
        for word in words:
            test_line = current_line + word + " "
            text_width = content_font.size(test_line)[0]
            
            # 如果当前行加上新词会超出宽度，则绘制当前行并开始新行
            if text_width > right_panel_width - 30:  # 左右边距各15
                if current_line:
                    text_surface = content_font.render(current_line, True, self.TEXT_COLOR)
                    self.screen.blit(text_surface, (right_panel_x + 15, content_y))
                    content_y += 20  # 行高
                    
                    # 检查是否超出区域高度
                    if content_y + 20 > commentary_y + commentary_height:
                        # 添加省略号
                        ellipsis = content_font.render("...", True, self.TEXT_COLOR)
                        self.screen.blit(ellipsis, (right_panel_x + right_panel_width - 30, content_y))
                        break
                current_line = word + " "
            else:
                current_line = test_line
        
        # 绘制最后一行
        if current_line and content_y + 20 <= commentary_y + commentary_height:
            text_surface = content_font.render(current_line, True, self.TEXT_COLOR)
            self.screen.blit(text_surface, (right_panel_x + 15, content_y))

    def draw_score_curve(self):
        """绘制红黑双方的分数曲线，移到右侧面板"""
        # 右侧面板参数 - 宽度增加到480像素
        right_panel_x = self.width - 470
        right_panel_width = 460

        # 定义曲线绘制区域，利用更宽的面板
        curve_width = right_panel_width - 20  # 更宽的图表区域
        curve_height = 150
        curve_x = right_panel_x
        # 计算曲线的Y位置，放在按钮上方
        curve_y = self.height - 400

        # 绘制背景矩形
        pygame.draw.rect(
            self.screen,
            (255, 255, 255),
            (curve_x, curve_y, curve_width, curve_height),
            border_radius=5,
        )
        pygame.draw.rect(
            self.screen,
            (0, 0, 0),
            (curve_x, curve_y, curve_width, curve_height),
            1,
            border_radius=5,
        )

        # 绘制标题
        curve_font = self._get_font(14)
        curve_title = curve_font.render("分数曲线", True, self.TEXT_COLOR)
        self.screen.blit(curve_title, (curve_x + 10, curve_y + 5))

        # 定义分数范围
        min_score = -500
        max_score = 500

        # 绘制刻度线和标签
        # Y轴（分数轴）
        for i in range(5):
            score = min_score + (max_score - min_score) * i // 4
            y_pos = (
                curve_y
                + curve_height
                - 10
                - ((score - min_score) / (max_score - min_score)) * (curve_height - 30)
            )
            pygame.draw.line(
                self.screen,
                (180, 180, 180),
                (curve_x + 10, y_pos),
                (curve_x + curve_width - 10, y_pos),
                1,
            )

            if i % 2 == 0:  # 只显示主要刻度的标签
                score_text = curve_font.render(str(score), True, self.TEXT_COLOR)
                self.screen.blit(
                    score_text,
                    (curve_x + curve_width - score_text.get_width() - 10, y_pos - 7),
                )

        # 将当前分数添加到历史记录中
        if self.red_best_move_score is not None and (
            not self.history_red_scores
            or self.history_red_scores[-1] != self.red_best_move_score
        ):
            self.history_red_scores.append(self.red_best_move_score)
            # 保持历史记录不超过最大点数
            if len(self.history_red_scores) > self.max_history_points:
                self.history_red_scores.pop(0)

        if self.black_best_move_score is not None and (
            not self.history_black_scores
            or self.history_black_scores[-1] != self.black_best_move_score
        ):
            self.history_black_scores.append(self.black_best_move_score)
            # 保持历史记录不超过最大点数
            if len(self.history_black_scores) > self.max_history_points:
                self.history_black_scores.pop(0)

        # 绘制红方历史分数点和连接线（使用红色）
        if len(self.history_red_scores) > 1:
            # 计算每个历史点的X位置
            step = (curve_width - 40) / (self.max_history_points - 1)
            points = []

            # 计算所有历史点的屏幕坐标
            for i, score in enumerate(self.history_red_scores):
                x_pos = curve_x + 20 + i * step
                y_pos = (
                    curve_y
                    + curve_height
                    - 10
                    - ((score - min_score) / (max_score - min_score))
                    * (curve_height - 30)
                )
                points.append((x_pos, y_pos))

            # 绘制连接线
            pygame.draw.lines(self.screen, self.RED_COLOR, False, points, 2)

            # 绘制每个历史点
            for point in points:
                pygame.draw.circle(
                    self.screen, self.RED_COLOR, (int(point[0]), int(point[1])), 3
                )

        # 绘制黑方历史分数点和连接线（使用黑色）
        if len(self.history_black_scores) > 1:
            # 计算每个历史点的X位置
            step = (curve_width - 40) / (self.max_history_points - 1)
            points = []

            # 计算所有历史点的屏幕坐标
            for i, score in enumerate(self.history_black_scores):
                x_pos = curve_x + 20 + i * step
                y_pos = (
                    curve_y
                    + curve_height
                    - 10
                    - ((score - min_score) / (max_score - min_score))
                    * (curve_height - 30)
                )
                points.append((x_pos, y_pos))

            # 绘制连接线
            pygame.draw.lines(self.screen, self.BLACK_COLOR, False, points, 2)

            # 绘制每个历史点
            for point in points:
                pygame.draw.circle(
                    self.screen, self.BLACK_COLOR, (int(point[0]), int(point[1])), 3
                )

        # 绘制当前局面分数点
        if self.current_move_score is not None:
            # 计算分数在图表中的位置
            score_pos = (
                curve_y
                + curve_height
                - 10
                - ((self.current_move_score - min_score) / (max_score - min_score))
                * (curve_height - 30)
            )

            # 绘制当前分数点（红色）
            pygame.draw.circle(
                self.screen, self.RED_COLOR, (curve_x + curve_width - 20, score_pos), 5
            )

        # 绘制图例 - 调整位置
        legend_y = curve_y + curve_height - 20
        # 红方最优图例
        pygame.draw.circle(self.screen, self.RED_COLOR, (curve_x + 20, legend_y), 3)
        legend_text = curve_font.render("红方分数", True, self.TEXT_COLOR)
        self.screen.blit(legend_text, (curve_x + 30, legend_y - 7))

        # 黑方最优图例
        pygame.draw.circle(self.screen, self.BLACK_COLOR, (curve_x + 130, legend_y), 3)
        legend_text = curve_font.render("黑方分数", True, self.TEXT_COLOR)
        self.screen.blit(legend_text, (curve_x + 140, legend_y - 7))

    def draw_status_info(self, fen):
        """绘制状态信息，移到右侧面板"""
        # 解析FEN信息
        parts = fen.split()
        turn = "红方回合" if parts[1] == "w" else "黑方回合"

        # 显示FEN字符串 - 改为单行显示
        status_font = self._get_font(16)

        # 右侧面板参数 - 使用统一的右侧面板宽度
        right_panel_x = self.width - 470
        right_panel_width = 460
        right_panel_y = 20

        # 绘制右侧面板背景
        pygame.draw.rect(
            self.screen,
            (235, 235, 235),
            (
                right_panel_x - 10,
                right_panel_y - 10,
                right_panel_width + 20,
                self.height - 2 * right_panel_y + 20,
            ),
            border_radius=5,
        )

        # FEN字符串单行显示
        fen_text = status_font.render(f"当前FEN: {fen}", True, self.TEXT_COLOR)

        # 绘制FEN信息（单行）
        y_pos = right_panel_y
        self.screen.blit(fen_text, (right_panel_x, y_pos))

        # 显示当前回合
        y_pos += 25
        turn_text = status_font.render(turn, True, self.TEXT_COLOR)
        self.screen.blit(turn_text, (right_panel_x, y_pos))

        # 显示推荐走法信息
        if self.current_move_text:
            y_pos += 25
            move_text = status_font.render(
                f"当前推荐走法: {self.current_move_text}", True, self.TEXT_COLOR
            )
            self.screen.blit(move_text, (right_panel_x, y_pos))

        # 显示红方最优走法信息
        if self.red_best_move_text:
            y_pos += 25
            # 构建符合要求的显示文本
            if hasattr(self, "red_best_move_chinese") and self.red_best_move_chinese:
                # 移除中文棋步前的"红 "前缀，因为格式要求已经在标签中包含了
                chinese_move = self.red_best_move_chinese.replace("红 ", "")
                score_text = (
                    f"+{self.red_best_move_score}"
                    if hasattr(self, "red_best_move_score")
                    and self.red_best_move_score is not None
                    else ""
                )
                red_move_text = status_font.render(
                    f"黑方最优招法：{chinese_move}({self.red_best_move_text}) {score_text}",
                    True,
                    (0, 200, 0),
                )
            else:
                score_text = (
                    f"+{self.red_best_move_score}"
                    if hasattr(self, "red_best_move_score")
                    and self.red_best_move_score is not None
                    else ""
                )
                red_move_text = status_font.render(
                    f"黑方最优招法：{self.red_best_move_text} {score_text}",
                    True,
                    (0, 200, 0),
                )
            self.screen.blit(red_move_text, (right_panel_x, y_pos))

        # 显示黑方最优走法信息
        if self.black_best_move_text:
            y_pos += 25
            # 构建符合要求的显示文本
            if (
                hasattr(self, "black_best_move_chinese")
                and self.black_best_move_chinese
            ):
                # 移除中文棋步前的"黑"前缀，因为格式要求已经在标签中包含了
                chinese_move = self.black_best_move_chinese.replace("黑", "")
                score_text = (
                    f"{self.black_best_move_score}"
                    if hasattr(self, "black_best_move_score")
                    and self.black_best_move_score is not None
                    else ""
                )
                black_move_text = status_font.render(
                    f"红方最优招法：{chinese_move}({self.black_best_move_text}){score_text}",
                    True,
                    (0, 0, 200),
                )
            else:
                score_text = (
                    f"{self.black_best_move_score}"
                    if hasattr(self, "black_best_move_score")
                    and self.black_best_move_score is not None
                    else ""
                )
                black_move_text = status_font.render(
                    f"红方最优招法：{self.black_best_move_text} {score_text}",
                    True,
                    (0, 0, 200),
                )
            self.screen.blit(black_move_text, (right_panel_x, y_pos))

        # 保存当前y_pos，供draw_score_curve使用
        self.status_info_bottom_y = y_pos + 30  # 额外留30像素间距

        # 绘制LLM文字解说
        self.draw_llm_commentary()

        # 绘制分数曲线
        self.draw_score_curve()

    def get_board_position(self, pos):
        """将屏幕坐标转换为棋盘坐标"""
        x, y = pos
        col = int(round((x - self.board_x) / self.cell_size))
        row = int(round((y - self.board_y) / self.cell_size))

        if 0 <= col < 9 and 0 <= row < 10:
            return (row, col)
        return None

    def board_to_fen(self, board_state, turn="w"):
        """将棋盘状态转换为FEN字符串，支持指定回合"""
        fen_parts = []
        for row in board_state:
            fen_row = []
            empty_count = 0
            for cell in row:
                if cell == ".":
                    empty_count += 1
                else:
                    if empty_count > 0:
                        fen_row.append(str(empty_count))
                        empty_count = 0
                    fen_row.append(cell)
            if empty_count > 0:
                fen_row.append(str(empty_count))
            fen_parts.append("".join(fen_row))

        # 使用传入的回合信息
        return "/".join(fen_parts) + f" {turn} - - 0 1"

    def fen_to_board(self, fen):
        """将FEN字符串转换为棋盘状态"""
        board_part = fen.split()[0]
        ranks = board_part.split("/")

        board = []
        for rank in ranks:
            row = []
            for char in rank:
                if char.isdigit():
                    # 添加空位置
                    row.extend(["." for _ in range(int(char))])
                else:
                    row.append(char)
            board.append(row)

        return board

    def parse_fen(self, fen_text):
        """解析用户输入的FEN字符串"""
        # 简单验证FEN格式是否正确
        try:
            # 移除首尾空白字符
            fen_text = fen_text.strip()
            parts = fen_text.split()

            # 提取棋盘部分
            board_part = parts[0]

            # 验证棋盘部分格式
            ranks = board_part.split("/")
            if len(ranks) != 10:
                raise ValueError("FEN格式错误: 行数量不正确，中国象棋应为10行")

            for rank in ranks:
                row_length = 0
                for char in rank:
                    if char.isdigit():
                        row_length += int(char)
                    else:
                        # 验证字符是否为有效的中国象棋棋子符号
                        if char not in "rnbakcpRNBAKCP":
                            raise ValueError(f"FEN格式错误: 非法的棋子字符 '{char}'")
                        row_length += 1
                if row_length != 9:
                    raise ValueError("FEN格式错误: 列数量不正确，中国象棋应为9列")

            # 如果输入不完整，添加默认值
            if len(parts) < 4:
                fen = board_part + " w - - 0 1"
            else:
                fen = fen_text

            return fen
        except Exception as e:
            print(f"FEN解析错误: {e}")
            return None

    def convert_api_moves_to_chinese(self):
        """将云库查询的招法转换为中文棋步列表"""
        chinese_moves = []
        current_board = None
        current_turn = "w"  # 默认红方回合

        # 遍历云库查询结果，先找到棋盘状态信息
        for i, line in enumerate(self.api_results):
            if line.startswith("board:"):
                # 提取棋盘部分
                board_part = line.split(":")[1].strip()
                # 尝试找到对应的回合信息
                for j in range(i + 1, min(i + 10, len(self.api_results))):
                    if self.api_results[j].startswith("turn:"):
                        current_turn = self.api_results[j].split(":")[1].strip()
                        break
                current_board = board_part + " " + current_turn
                break

        # 遍历云库查询结果中的所有招法
        for line in self.api_results:
            if line.startswith("move:"):
                # 提取move后面的内容，格式: move:b2b9,score:-322,rank:0,note:? (41-01),winrate:27.37
                move_part = line[5:].split(",")[0].strip()  # 获取b2b9部分

                # 解析走法坐标
                parsed_move = self._parse_move(move_part)
                if parsed_move:
                    from_col, from_row, to_col, to_row = parsed_move

                    # 使用找到的棋盘状态构建FEN
                    if current_board:
                        # 构建完整的FEN字符串
                        temp_fen = current_board + " - - 0 1"
                        try:
                            # 转换为中文棋步
                            chinese_move = self._coord_to_chinese_move(
                                temp_fen, from_col, from_row, to_col, to_row
                            )
                            # 添加到中文棋步列表
                            chinese_moves.append(chinese_move)
                            # 同时添加原始行信息以便参考
                            chinese_moves.append(f"  ({line})")
                        except Exception as e:
                            # 如果转换失败，添加原始走法信息
                            chinese_moves.append(
                                f"无法转换: {move_part} (错误: {str(e)})"
                            )

        return chinese_moves

    def query_chessdb_llm(self, fen):
        """查询LLM文字解说"""
        try:
            print("正在获取LLM文字解说...")
            self.llm_commentary_loading = True
            
            # 从fen提取board部分和当前回合
            parts = fen.split(" ")
            board_part = parts[0]
            current_turn = parts[1] if len(parts) > 1 else "w"
            
            # 构建LLM API参数
            params = {
                "lang": "0",
                "action": "ccllm",
                "board": fen
            }
            
            headers = {
                "Accept": "text/event-stream",
                "Authorization": "www.chessdb.cn",
                "referer": "https://www.chessdb.cn/query/"
            }
            
            # 发送请求
            response = requests.get(self.llm_commentary_url, params=params, headers=headers, stream=True, timeout=15)
            response.raise_for_status()
            
            # 解析SSE响应
            commentary = ""
            for line in response.iter_lines():
                if line:
                    decoded_line = line.decode('utf-8')
                    # 查找data字段
                    if decoded_line.startswith("data:"):
                        data_content = decoded_line[5:].strip()
                        if data_content:
                            commentary += data_content + "\n"
                    # 检查是否结束
                    if decoded_line == "event:end":
                        break
            
            # 处理解说内容
            if commentary:
                self.llm_commentary = commentary.strip()
                print(f"获取到LLM文字解说: {self.llm_commentary}")
            else:
                self.llm_commentary = "未能获取局面解说"
                print("未获取到文字解说")
                
        except Exception as e:
            self.llm_commentary = f"获取解说失败: {str(e)}"
            print(f"LLM查询错误: {e}")
        finally:
            self.llm_commentary_loading = False

    def query_chessdb(self, fen):
        """查询中国象棋云库API"""
        # 重置所有推荐走法
        self.api_results = []
        self.current_move = None
        self.current_move_text = ""
        self.red_best_move = None
        self.red_best_move_text = ""
        self.black_best_move = None
        self.black_best_move_text = ""
        self.chinese_moves = []  # 新增中文棋步列表
        print(f"查询FEN: {fen}")
        print(f"查询URL: {self.chessdb_api_url}")
        try:
            # 1. 查询当前局面的最优走法

            # 从fen提取board部分和当前回合
            parts = fen.split(" ")
            board_part = parts[0]
            current_turn = parts[1] if len(parts) > 1 else "w"

            # 保存为实例变量，供其他方法使用
            self.board_part = board_part
            self.current_turn = current_turn

            # 2. 只在需要时查询红先和黑先的最优走法
            self.api_results.append("\n===== 红先候选走法 =====")
            self._query_chessdb_by_turn(board_part, "w", is_red=True)

            self.api_results.append("\n===== 黑先候选走法 =====")
            self._query_chessdb_by_turn(board_part, "b")

            # 修复Q键查询结果显示问题：不显示界面结果
            self.show_api_results = False
            print(f"查询成功，总结果行数: {len(self.api_results)}")

            # 转换云库招法为中文棋步列表
            self.chinese_moves = self.convert_api_moves_to_chinese()

            # 将结果输出到控制台
            for line in self.api_results:
                print(line)

            # 输出中文棋步列表
            if self.chinese_moves:
                print("\n中文棋步列表：")
                for move in self.chinese_moves:
                    print(move)
            
            # 添加LLM文字解说查询
            self.query_chessdb_llm(fen)

        except requests.RequestException as e:
            print(f"云库API查询错误: {e}")
            self.api_results = [f"查询失败: {str(e)}"]
            self.show_api_results = False
            print(f"查询失败: {str(e)}")
            # 即使API查询失败，也尝试获取LLM解说
            try:
                self.query_chessdb_llm(fen)
            except:
                pass

    def _query_chessdb_by_turn(self, board_part, turn, is_current=False, is_red=False):
        """根据指定的回合查询最优走法"""
        # 确保board_part格式正确
        board_part = board_part.strip()
        
        # 构建完整FEN
        full_board_fen = f"{board_part} {turn} - - 0 1"
        print(f"使用的完整FEN串: {full_board_fen}")
        
        # API调用
        query_url = "http://www.chessdb.cn/chessdb.php?action=queryall"
        params = {"board": full_board_fen}

        try:
            print(f"查询 {'红先' if turn == 'w' else '黑先'} 最优走法...")
            response = requests.get(query_url, params=params, timeout=10)
            print(f"响应状态码: {response.status_code}")
            print(f"响应内容: {response.text[:200]}...")
            
            response.raise_for_status()

            # 解析响应内容
            result_lines = response.text.strip().split("|")
            print(f"解析到的行数: {len(result_lines)}")
            
            # 处理走法
            for line in result_lines:
                if line.startswith("move:"):
                    move_part = line[5:].split(",")[0].strip("\n")
                    print(f"原始走法: {move_part}")
                    
                    # 提取分数和胜率信息
                    score = None
                    winrate = None
                    if "score:" in line:
                        score_part = line.split("score:")[1].split(",")[0].strip()
                        try:
                            score = int(score_part)
                        except:
                            pass
                    if "winrate:" in line:
                        winrate_part = line.split("winrate:")[1].strip()
                        try:
                            winrate = float(winrate_part)
                        except:
                            pass
                    print(f"提取到的分数: {score}, 胜率: {winrate}")
                    
                    # 解析走法
                    parsed_move = self._parse_move(move_part)
                    if parsed_move:
                        from_col, from_row, to_col, to_row = parsed_move
                        
                        # 使用完整的FEN字符串进行中文棋步转换
                        try:
                            chinese_move = self._coord_to_chinese_move(
                                full_board_fen, from_col, from_row, to_col, to_row
                            )
                            print(f"转换后的中文棋步: {chinese_move}")
                            
                            # 保存走法信息和胜率
                            if is_current:
                                self.current_move = parsed_move
                                self.current_move_text = move_part
                                self.current_move_chinese = chinese_move
                            elif is_red:
                                self.red_best_move = parsed_move
                                self.red_best_move_text = move_part
                                self.red_best_move_score = score
                                self.red_best_move_winrate = winrate
                                self.red_best_move_chinese = chinese_move
                            else:
                                self.black_best_move = parsed_move
                                self.black_best_move_text = move_part
                                self.black_best_move_score = score
                                self.black_best_move_winrate = winrate
                                self.black_best_move_chinese = chinese_move
                                
                            # 只处理第一个走法
                            return
                        except Exception as e:
                            print(f"中文棋步转换错误: {str(e)}")
                            chinese_move = f"转换失败: {str(e)}"
                    
        except Exception as e:
            print(f"API查询错误: {str(e)}")

    def convert_move_to_chinese(self, move_part, board_part, turn):
        """将走法转换为中文棋步"""
        # 解析走法坐标
        parsed_move = self._parse_move(move_part)
        if parsed_move:
            from_col, from_row, to_col, to_row = parsed_move

            # 构建完整的FEN字符串
            full_fen = f"{board_part} {turn} - - 0 1"

            try:
                # 使用现有方法转换为中文棋步
                chinese_move = self._coord_to_chinese_move(
                    full_fen, from_col, from_row, to_col, to_row
                )
                return chinese_move
            except Exception as e:
                return f"无法转换: {move_part} (错误: {str(e)})"
        return f"无效走法格式: {move_part}"

    def test_move_conversion(self):
        """测试将黑方候选走法转换为中文棋步"""
        # 假设当前棋盘状态（需要替换为实际的棋盘状态）
        # 这里使用一个示例棋盘状态，您需要替换为实际的棋盘部分
        board_part = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR"

        # 用户提供的黑方候选走法列表
        black_moves = [
            "move:h7g7,score:-1,rank:2,note:! (45-16),winrate:49.92",
            "move:c6c5,score:-1,rank:2,note:! (44-21),winrate:49.92",
            "move:g9e7,score:-16,rank:0,note:? (44-02),winrate:48.79",
            "move:c9e7,score:-53,rank:0,note:? (44-04),winrate:45.99",
            "move:h9i7,score:-60,rank:0,note:? (43-01),winrate:45.47",
        ]

        print("\n黑方候选走法中文转换结果：")
        for move_line in black_moves:
            # 提取move部分
            move_part = move_line[5:].split(",")[0].strip()
            # 转换为中文棋步
            chinese_move = self.convert_move_to_chinese(move_part, board_part, "b")
            # 提取分数和胜率信息
            score = None
            winrate = None
            if "score:" in move_line:
                score_part = move_line.split("score:")[1].split(",")[0].strip()
                try:
                    score = int(score_part)
                except:
                    pass
            if "winrate:" in move_line:
                winrate_part = move_line.split("winrate:")[1].strip()
                try:
                    winrate = float(winrate_part)
                except:
                    pass
            # 输出结果
            print(f"{chinese_move} | 分数: {score} | 胜率: {winrate:.2f}%")

    def reset_game(self, initial_fen):
        """重置游戏状态"""
        # 重置拖拽状态
        self.dragging = False
        self.dragged_piece = None
        self.selected_pos = None
        
        # 重置走子标记
        self.move_start_pos = None
        self.move_end_pos = None
        
        # 重置历史记录
        self.fen_history = [initial_fen]
        
        # 重置推荐走法
        self.current_move = None
        self.current_move_text = ""
        self.red_best_move = None
        self.red_best_move_text = ""
        self.black_best_move = None
        self.black_best_move_text = ""
        
        # 重置闪烁效果
        self.flash_position = None
        self.flash_timer = 0
        self.flash_count = 0
        
        return initial_fen

    def toggle_board_flip(self):
        """翻转棋盘"""
        self.board_flipped = not self.board_flipped
        
    def load_piece_images(self):
        """加载所有风格的棋子图片"""
        print("开始加载棋子图片...")
        
        # 定义棋子类型到图片文件名的映射
        piece_map = {
            'R': 'RR',  # 红车
            'N': 'RN',  # 红马
            'B': 'RB',  # 红相
            'A': 'RA',  # 红仕
            'K': 'RK',  # 红帅
            'C': 'RC',  # 红炮
            'P': 'RP',  # 红兵
            'r': 'BR',  # 黑车
            'n': 'BN',  # 黑马
            'b': 'BB',  # 黑象
            'a': 'BA',  # 黑士
            'k': 'BK',  # 黑将
            'c': 'BC',  # 黑炮
            'p': 'BP',  # 黑卒
            'selected': 'OOS'  # 选中状态
        }
        
        # 定义可用的棋子风格
        styles = ['DELICATE', 'POLISH', 'WOOD']
        
        # 确保piece_images字典已初始化
        if not hasattr(self, 'piece_images') or self.piece_images is None:
            self.piece_images = {}
            print("初始化piece_images字典")
        
        # 确保current_piece_style已设置
        if not hasattr(self, 'current_piece_style') or self.current_piece_style is None:
            self.current_piece_style = 'DELICATE'  # 默认使用DELICATE风格
            print(f"设置默认棋子风格为: {self.current_piece_style}")
        
        # 加载每种风格的棋子图片
        for style in styles:
            self.piece_images[style] = {}
            loaded_count = 0
            failed_count = 0
            print(f"加载{style}风格棋子图片...")
            
            for piece, file_name in piece_map.items():
                # 构建图片路径
                img_path = os.path.join('images', style, f'{file_name}.GIF')
                
                # 获取绝对路径用于调试
                abs_path = os.path.abspath(img_path)
                
                try:
                    # 加载图片
                    image = pygame.image.load(img_path)
                    # 转换为带有alpha通道的格式
                    image = image.convert_alpha()
                    self.piece_images[style][piece] = image
                    loaded_count += 1
                except Exception as e:
                    print(f"加载失败 {abs_path}: {e}")
                    # 如果加载失败，保持为None，后续会处理
                    self.piece_images[style][piece] = None
                    failed_count += 1
            
            print(f"{style}风格加载完成: 成功 {loaded_count} 张, 失败 {failed_count} 张")
        
        # 加载所有可用的棋盘背景图片
        print("开始加载棋盘背景图片...")
        board_images_loaded = 0
        
        # 定义棋盘图片文件列表（从images目录下的GIF文件中筛选）
        board_image_files = ['WOOD.GIF', 'GREEN.GIF', 'CANVAS.GIF', 'WHITE.GIF', 'SKELETON.GIF', 'SHEET.GIF', 'QIANHONG.GIF']
        
        for board_file in board_image_files:
            try:
                board_img_path = os.path.join('images', board_file)
                abs_board_path = os.path.abspath(board_img_path)
                
                # 加载棋盘图片
                board_image = pygame.image.load(board_img_path)
                board_image = board_image.convert()
                
                # 获取不带扩展名的文件名作为风格名称
                style_name = os.path.splitext(board_file)[0]
                self.board_images[style_name] = board_image
                board_images_loaded += 1
                print(f"成功加载棋盘背景图片: {style_name} ({abs_board_path})")
            except Exception as e:
                print(f"加载棋盘背景图片失败 {board_file}: {e}")
        
        # 设置当前棋盘图片
        if self.current_board_style in self.board_images:
            self.board_image = self.board_images[self.current_board_style]
        elif self.board_images:
            # 如果默认风格不存在，使用第一个可用的风格
            first_style = next(iter(self.board_images.keys()))
            self.current_board_style = first_style
            self.board_image = self.board_images[first_style]
            print(f"默认棋盘风格{self.current_board_style}不存在，使用第一个可用风格: {first_style}")
        
        print(f"棋盘背景图片加载完成！成功加载 {board_images_loaded} 张")
        print("棋子图片加载完成！")
            
    def switch_piece_style(self):
        """切换棋子风格（在DELICATE、POLISH、WOOD之间循环）"""
        styles = ['DELICATE', 'POLISH', 'WOOD']
        current_index = styles.index(self.current_piece_style)
        next_index = (current_index + 1) % len(styles)
        self.current_piece_style = styles[next_index]
        print(f"已切换棋子风格为: {self.current_piece_style}")
        
    def switch_board_style(self):
        """切换棋盘风格（在所有加载的棋盘样式之间循环）"""
        if not self.board_images:
            print("没有可用的棋盘样式可以切换")
            return
        
        # 获取所有可用的棋盘风格列表
        board_styles = list(self.board_images.keys())
        
        # 找到当前风格的索引
        if self.current_board_style in board_styles:
            current_index = board_styles.index(self.current_board_style)
        else:
            current_index = 0
            
        # 计算下一个风格的索引
        next_index = (current_index + 1) % len(board_styles)
        self.current_board_style = board_styles[next_index]
        self.board_image = self.board_images[self.current_board_style]
        
        print(f"已切换棋盘风格为: {self.current_board_style}")
        


    def draw_buttons(self):
        """绘制按钮"""
        # 获取鼠标位置，用于检测悬停
        mouse_pos = pygame.mouse.get_pos()

        # 绘制悔棋按钮
        undo_color = (
            self.button_hover_color
            if self.undo_button.collidepoint(mouse_pos)
            else self.button_color
        )
        pygame.draw.rect(self.screen, undo_color, self.undo_button)
        pygame.draw.rect(self.screen, (0, 0, 0), self.undo_button, 2)  # 按钮边框

        button_font = self._get_font(24)
        undo_text = button_font.render("悔棋", True, self.button_text_color)
        text_rect = undo_text.get_rect(center=self.undo_button.center)
        self.screen.blit(undo_text, text_rect)

        # 绘制重新开局按钮
        reset_color = (
            self.button_hover_color
            if self.reset_button.collidepoint(mouse_pos)
            else self.button_color
        )
        pygame.draw.rect(self.screen, reset_color, self.reset_button)
        pygame.draw.rect(self.screen, (0, 0, 0), self.reset_button, 2)  # 按钮边框

        # 按钮文本
        reset_text = button_font.render("重新开局", True, self.button_text_color)
        text_rect = reset_text.get_rect(center=self.reset_button.center)
        self.screen.blit(reset_text, text_rect)

        # 绘制翻转棋盘按钮
        flip_color = (
            self.button_hover_color
            if self.flip_button.collidepoint(mouse_pos)
            else self.button_color
        )
        pygame.draw.rect(self.screen, flip_color, self.flip_button)
        pygame.draw.rect(self.screen, (0, 0, 0), self.flip_button, 2)  # 按钮边框

        flip_text = button_font.render("翻转棋盘", True, self.button_text_color)
        text_rect = flip_text.get_rect(center=self.flip_button.center)
        self.screen.blit(flip_text, text_rect)

        # 绘制字体切换按钮
        font_color = (
            self.button_hover_color
            if self.font_button.collidepoint(mouse_pos)
            else self.button_color
        )
        pygame.draw.rect(self.screen, font_color, self.font_button)
        pygame.draw.rect(self.screen, (0, 0, 0), self.font_button, 2)  # 按钮边框

        # 将按钮文字改为"切换棋子"
        font_text = button_font.render("切换棋子", True, self.button_text_color)
        text_rect = font_text.get_rect(center=self.font_button.center)
        self.screen.blit(font_text, text_rect)

    def render(self, initial_fen):
        """渲染整个棋盘和棋子"""
        running = True
        clock = pygame.time.Clock()
        current_fen = initial_fen
        current_board = self.fen_to_board(current_fen)
        
        # 初始化历史记录，保存初始局面
        self.fen_history = [initial_fen]
        
        while running:
            # 更新窗口标题，包含推荐走法
            if self.current_move_text:
                pygame.display.set_caption(
                    f"中国象棋棋盘渲染 - 推荐走法: {self.current_move_text}"
                )
            else:
                pygame.display.set_caption("图灵AI中国象棋智能棋盘")

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        if self.input_active:
                            self.input_active = False
                            self.input_text = ""
                        else:
                            running = False
                    elif event.key == pygame.K_t and not self.input_active:
                        # 按T键激活FEN输入框
                        self.input_active = True
                        self.input_text = current_fen.split()[0]  # 默认显示当前棋盘部分
                    elif event.key == pygame.K_q:
                        # 按Q键查询云库或关闭结果
                        # 修复：始终执行查询，不显示界面结果
                        self.query_chessdb(current_fen)
                    elif event.key == pygame.K_s and not self.input_active:
                        # 按S键切换棋子风格
                        self.switch_piece_style()
                    elif event.key == pygame.K_b and not self.input_active:
                        # 按B键切换棋盘风格
                        self.switch_board_style()
                    elif event.key == pygame.K_RETURN and self.input_active:
                        # 确认FEN输入
                        parsed_fen = self.parse_fen(self.input_text)
                        if parsed_fen:
                            current_fen = parsed_fen
                            current_board = self.fen_to_board(current_fen)
                            # 更新历史记录
                            self.fen_history = [current_fen]
                            # 清除之前的推荐走法
                            self.current_move = None
                            self.current_move_text = ""
                            self.red_best_move = None
                            self.red_best_move_text = ""
                            self.black_best_move = None
                            self.black_best_move_text = ""

                            # 自动查询云库获取下一步推荐走法
                            self.query_chessdb(current_fen)

                        # 重置拖拽状态
                        self.dragging = False
                        self.dragged_piece = None
                        self.selected_pos = None
                # 添加鼠标事件处理
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if (
                        event.button == 1 and not self.input_active
                    ):  # 左键点击且输入框未激活
                        mouse_pos = pygame.mouse.get_pos()
                        # 检查是否点击重新开局按钮
                        if self.reset_button.collidepoint(mouse_pos):
                            current_fen = self.reset_game(initial_fen)
                            current_board = self.fen_to_board(current_fen)
                            # 重置历史记录，保存初始局面
                            self.fen_history = [initial_fen]
                        # 检查是否点击翻转棋盘按钮
                        elif self.flip_button.collidepoint(mouse_pos):
                            self.toggle_board_flip()
                        # 检查是否点击悔棋按钮
                        elif self.undo_button.collidepoint(mouse_pos):
                            if len(self.fen_history) > 1:
                                # 移除当前局面
                                self.fen_history.pop()
                                # 恢复到上一个局面
                                current_fen = self.fen_history[-1]
                                current_board = self.fen_to_board(current_fen)
                                
                                # 重置状态
                                self.selected_pos = None
                                self.dragging = False
                                self.dragged_piece = None
                                self.move_start_pos = None
                                self.move_end_pos = None
                                
                                # 清除之前的推荐走法
                                self.current_move = None
                                self.current_move_text = ""
                                self.red_best_move = None
                                self.red_best_move_text = ""
                                self.black_best_move = None
                                self.black_best_move_text = ""
                                
                                # 自动查询云库获取下一步推荐走法
                                self.query_chessdb(current_fen)
                        # 检查是否点击字体切换按钮
                        elif self.font_button.collidepoint(mouse_pos):
                            # 切换到下一个字体
                            self.current_font_index = (
                                self.current_font_index + 1
                            ) % len(self.available_fonts)
                            self.current_font_name = self.available_fonts[
                                self.current_font_index
                            ]
                            # 更新字体对象
                            self.font = self._get_font(30)
                            self.small_font = self._get_font(16)
                        # 检查是否点击在棋盘上
                        elif (
                            self.board_x
                            <= mouse_pos[0]
                            <= self.board_x + self.board_width
                            and self.board_y
                            <= mouse_pos[1]
                            <= self.board_y + self.board_height
                        ):
                            # 计算点击的棋盘坐标
                            col_float = (mouse_pos[0] - self.board_x) / self.cell_size
                            row_float = (mouse_pos[1] - self.board_y) / self.cell_size
                            display_col = round(col_float)
                            display_row = round(row_float)

                            # 根据翻转状态转换为实际棋盘坐标
                            if self.board_flipped:
                                col = 8 - display_col
                                row = 9 - display_row
                            else:
                                col = display_col
                                row = display_row

                            # 确保坐标有效
                            if 0 <= col < 9 and 0 <= row < 10:
                                # 获取该位置的棋子
                                board_part = current_fen.split()[0]
                                ranks = board_part.split("/")
                                if row < len(ranks):
                                    rank = ranks[row]
                                    file_idx = 0
                                    piece_char = None
                                    for char in rank:
                                        if char.isdigit():
                                            file_idx += int(char)
                                        else:
                                            if file_idx == col:
                                                piece_char = char
                                                break
                                            file_idx += 1

                                # 如果已经选中了一个棋子，并且点击了另一个位置，则尝试移动棋子
                                if self.selected_pos and (row, col) != self.selected_pos:
                                    # 模拟拖拽释放，执行移动逻辑
                                    from_row, from_col = self.selected_pos
                                    
                                    # 保存移动的起点和终点位置，用于绘制圆圈标记
                                    self.move_start_pos = (from_row, from_col)
                                    self.move_end_pos = (row, col)
                                    
                                    # 移动棋子（复用拖拽释放时的移动逻辑）
                                    board_part = current_fen.split()[0]
                                    ranks = board_part.split("/")

                                    # 将棋盘转换为可修改的列表
                                    new_ranks = []
                                    for r in ranks:
                                        new_rank = []
                                        file_idx = 0
                                        for char in r:
                                            if char.isdigit():
                                                new_rank.extend(["." for _ in range(int(char))])
                                            else:
                                                new_rank.append(char)
                                        new_ranks.append(new_rank)

                                    # 移动棋子
                                    piece_char = new_ranks[from_row][from_col]
                                    new_ranks[from_row][from_col] = "."
                                    new_ranks[row][col] = piece_char

                                    # 将棋盘转换回FEN格式
                                    new_board_part = ""
                                    for r in new_ranks:
                                        empty_count = 0
                                        rank_str = ""
                                        for char in r:
                                            if char == ".":
                                                empty_count += 1
                                            else:
                                                if empty_count > 0:
                                                    rank_str += str(empty_count)
                                                    empty_count = 0
                                                rank_str += char
                                        if empty_count > 0:
                                            rank_str += str(empty_count)
                                        new_board_part += rank_str + "/"
                                    new_board_part = new_board_part.rstrip("/")

                                    # 更新FEN
                                    fen_parts = current_fen.split()
                                    new_fen = new_board_part
                                    if len(fen_parts) > 1:
                                        # 切换回合
                                        current_turn = fen_parts[1]
                                        new_turn = "b" if current_turn == "w" else "w"
                                        new_fen += f" {new_turn}"
                                        if len(fen_parts) > 2:
                                            new_fen += f" {' '.join(fen_parts[2:])}"

                                    # 保存移动前的FEN状态，用于生成中文棋步描述
                                    previous_fen = current_fen

                                    # 更新当前FEN
                                    current_fen = new_fen
                                    current_board = self.fen_to_board(current_fen)
                                    
                                    # 保存新的FEN到历史记录中
                                    self.fen_history.append(current_fen)

                                    # 设置闪烁效果
                                    self.flash_position = (row, col)
                                    self.flash_timer = pygame.time.get_ticks()
                                    self.flash_count = 0

                                    # 显示移动信息
                                    # 转换为标准坐标表示 a1b2 格式
                                    from_col_char = chr(ord("a") + from_col)
                                    to_col_char = chr(ord("a") + col)
                                    from_row_num = 10 - from_row
                                    to_row_num = 10 - row
                                    move_notation = f"{from_col_char}{from_row_num}{to_col_char}{to_row_num}"

                                    # 确定棋子颜色
                                    piece_color = "红" if piece_char.isupper() else "黑"

                                    # 获取棋子类型的中文名称
                                    piece_name = self.piece_symbols[piece_char][0]

                                    # 构建标准坐标移动信息
                                    move_text = f"{piece_color}{piece_name} {move_notation}"

                                    # 生成中文棋步描述
                                    chinese_move = self._coord_to_chinese_move(
                                        previous_fen,
                                        from_col,
                                        from_row,
                                        col,
                                        row,
                                    )

                                    # 单独保存中文棋步
                                    self.last_chinese_move = chinese_move

                                    # 优化显示格式
                                    full_move_text = (
                                        f"中文棋步: {chinese_move}\n\n标准坐标: {move_text}"
                                    )

                                    # 在控制台输出移动信息
                                    print(full_move_text)

                                    # 清除之前的推荐走法
                                    self.current_move = None
                                    self.current_move_text = ""
                                    self.red_best_move = None
                                    self.red_best_move_text = ""
                                    self.black_best_move = None
                                    self.black_best_move_text = ""

                                    # 自动查询云库获取最优走法
                                    self.query_chessdb(current_fen)

                                    # 重置选中状态
                                    self.selected_pos = None
                                    self.dragging = False
                                    self.dragged_piece = None
                                # 如果有棋子
                                elif piece_char and piece_char in self.piece_symbols:
                                    # 如果点击的是已经选中的棋子，则取消选择
                                    if self.selected_pos == (row, col):
                                        self.selected_pos = None
                                        self.dragging = False
                                        self.dragged_piece = None
                                        self.move_start_pos = None  # 清除起点标记
                                    else:
                                        # 选择新的棋子
                                        # 将dragging设为False，避免与拖拽功能冲突
                                        self.dragging = False
                                        self.selected_pos = (row, col)
                                        self.dragged_piece = self.piece_symbols[piece_char]
                                        self.drag_pos = mouse_pos
                                        self.move_start_pos = (row, col)  # 设置起点标记
                                        self.move_end_pos = None  # 清除终点标记
                                        # 点击空白处，取消选中
                                else:
                                    self.selected_pos = None
                                    self.dragging = False
                                    self.dragged_piece = None
                                    self.move_start_pos = None  # 清除起点标记
                                    self.move_end_pos = None    # 清除终点标记
                elif event.type == pygame.MOUSEBUTTONUP:
                    if event.button == 1 and self.dragging:  # 左键释放且正在拖拽
                        mouse_pos = pygame.mouse.get_pos()
                        # 计算释放位置的棋盘坐标
                        # 确保吸附到最近的交叉点，避免放错位置
                        col_float = (mouse_pos[0] - self.board_x) / self.cell_size
                        row_float = (mouse_pos[1] - self.board_y) / self.cell_size
                        display_col = int(round(col_float))
                        display_row = int(round(row_float))

                        # 根据翻转状态转换为实际棋盘坐标
                        if self.board_flipped:
                            col = 8 - display_col
                            row = 9 - display_row
                        else:
                            col = display_col
                            row = display_row

                        # 计算实际吸附的像素位置，确保精确对齐
                        snap_x = self.board_x + col * self.cell_size
                        snap_y = self.board_y + row * self.cell_size

                        # 确保坐标有效
                        if (
                            0 <= col < 9
                            and 0 <= row < 10
                            and (row, col) != self.selected_pos
                        ):
                            # 获取原始位置
                            from_row, from_col = self.selected_pos

                            # 尝试移动棋子
                            board_part = current_fen.split()[0]
                            ranks = board_part.split("/")

                            # 将棋盘转换为可修改的列表
                            new_ranks = []
                            for r in ranks:
                                new_rank = []
                                file_idx = 0
                                for char in r:
                                    if char.isdigit():
                                        new_rank.extend(["." for _ in range(int(char))])
                                    else:
                                        new_rank.append(char)
                                new_ranks.append(new_rank)

                            # 移动棋子
                            piece_char = new_ranks[from_row][from_col]
                            new_ranks[from_row][from_col] = "."
                            new_ranks[row][col] = piece_char

                            # 将棋盘转换回FEN格式
                            new_board_part = ""
                            for r in new_ranks:
                                empty_count = 0
                                rank_str = ""
                                for char in r:
                                    if char == ".":
                                        empty_count += 1
                                    else:
                                        if empty_count > 0:
                                            rank_str += str(empty_count)
                                            empty_count = 0
                                        rank_str += char
                                if empty_count > 0:
                                    rank_str += str(empty_count)
                                new_board_part += rank_str + "/"
                            new_board_part = new_board_part.rstrip("/")

                            # 更新FEN
                            fen_parts = current_fen.split()
                            new_fen = new_board_part
                            if len(fen_parts) > 1:
                                # 切换回合
                                current_turn = fen_parts[1]
                                new_turn = "b" if current_turn == "w" else "w"
                                new_fen += f" {new_turn}"
                                if len(fen_parts) > 2:
                                    new_fen += f" {' '.join(fen_parts[2:])}"

                            # 保存移动前的FEN状态，用于生成中文棋步描述
                            previous_fen = current_fen

                            # 更新当前FEN
                            current_fen = new_fen
                            current_board = self.fen_to_board(current_fen)
                            
                            # 保存新的FEN到历史记录中
                            self.fen_history.append(current_fen)

                            # 设置闪烁效果
                            self.flash_position = (row, col)
                            self.flash_timer = pygame.time.get_ticks()
                            self.flash_count = 0

                            # 显示移动信息
                            # 原坐标格式: 从 {from_pos} 到 {to_pos}
                            # 新坐标格式: 转换为a1b2格式
                            # 转换逻辑: 行从0-9变为1-10，列从0-8变为a-i
                            # 红方视角: 行从下往上是1-10，黑方视角相反
                            from_row_chess, from_col_chess = from_row, from_col
                            to_row_chess, to_col_chess = row, col

                            # 转换为标准坐标表示 a1b2 格式
                            # 列: 0->a, 1->b, ..., 8->i
                            from_col_char = chr(ord("a") + from_col_chess)
                            to_col_char = chr(ord("a") + to_col_chess)

                            # 行: 0->10, 1->9, ..., 9->1 (红方视角)
                            from_row_num = 10 - from_row_chess
                            to_row_num = 10 - to_row_chess

                            # 构建标准招法格式
                            move_notation = f"{from_col_char}{from_row_num}{to_col_char}{to_row_num}"

                            # 确定棋子颜色
                            piece_color = "红" if piece_char.isupper() else "黑"

                            # 获取棋子类型的中文名称
                            piece_name = self.piece_symbols[piece_char][0]

                            # 构建标准坐标移动信息
                            move_text = f"{piece_color}{piece_name} {move_notation}"

                            # 生成中文棋步描述 - 使用移动前的FEN状态
                            chinese_move = self._coord_to_chinese_move(
                                previous_fen,
                                from_col_chess,
                                from_row_chess,
                                to_col_chess,
                                to_row_chess,
                            )

                            # 单独保存中文棋步，便于其他地方使用
                            self.last_chinese_move = chinese_move

                            # 优化显示格式，突出中文棋步
                            full_move_text = (
                                f"中文棋步: {chinese_move}\n\n标准坐标: {move_text}"
                            )

                            # 创建隐藏的Tkinter窗口
                            # try:
                            #     root = tk.Tk()
                            #     root.withdraw()  # 隐藏主窗口
                            #     # 显示消息框
                            #     messagebox.showinfo("棋子移动", full_move_text)
                            #     root.destroy()
                            # except:
                            #     pass

                            # 在控制台也输出移动信息
                            print(full_move_text)

                            # 清除之前的推荐走法
                            self.current_move = None
                            self.current_move_text = ""
                            self.red_best_move = None
                            self.red_best_move_text = ""
                            self.black_best_move = None
                            self.black_best_move_text = ""

                            # 自动查询云库获取最优走法
                            self.query_chessdb(current_fen)

                        # 重置拖拽状态
                        self.dragging = False
                        self.dragged_piece = None
                        self.selected_pos = None
                elif event.type == pygame.MOUSEMOTION:
                    if self.dragging:
                        self.drag_pos = pygame.mouse.get_pos()

            # 绘制棋盘
            self.draw_board()

            # 绘制走子的起点和终点标记
            self.draw_move_markers()

            # 绘制棋子
            self.draw_pieces(current_fen)

            # 绘制状态信息
            self.draw_status_info(current_fen)

            # 绘制红黑双方最优招法 - 修改这里的方法名
            self.draw_move_arrow()

            # 绘制按钮
            self.draw_buttons()

            # 更新屏幕
            pygame.display.flip()

            # 控制帧率
            clock.tick(60)

        # 退出pygame
        pygame.quit()


if __name__ == "__main__":
    # 测试用FEN字符串（标准开局）
    default_fen = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w"

    # 从命令行参数获取FEN字符串，如果没有提供则使用默认值
    fen = sys.argv[1] if len(sys.argv) > 1 else default_fen

    # 创建渲染器并绘制棋盘
    renderer = ChineseChessRenderer()
    renderer.render(fen)
